/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.contrat.services.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Service;

import fr.generali.accueilclient.commun.exception.AccueilClientRechercheContratException;
import fr.generali.accueilclient.commun.exception.AccueilClientTechnicalException;
import fr.generali.accueilclient.contrat.om.IContrat;
import fr.generali.accueilclient.contrat.om.IContratRecherche;
import fr.generali.accueilclient.contrat.services.IContratService;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.services.IRechercherContratsWebService;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.ctr.descriptionsiegerisque.DTOProfilVehiculeAssure;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.ctr.elementscontrat.DTOSouscripteur;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.ctr.structurecontrat.DTOContrat;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.demande.DTODemande;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.services.RechercherContratsException;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.pty.portefeuille.DTOPortefeuilleContrat;
import fr.generali.souscriptiongestion.dommages.tosca.recherchercontrats.reponse.DTOReponse;

/**
 * @author Chaibi
 */
@Service
public class ContratService implements IContratService {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ContratService.class);

    /**
     * Aucun client trouvé
     */
    private static final String AUCUN_CLIENT = "recherche.contrat.aucun.client";

    /**
     * Constante message demande affiner les criteres
     */
    private static final String FORMULAIRE_AFFINE_CRITERES = "recherche.contrat.affiner.criteres";

    /**
     * Trop de contrats trouvés
     */
    private static final String RESULTAT_TROP_LARGE = "recherche.contrat.resultat.trop.large";

    /**
     * Le service ne répond pas
     */
    private static final String SERVICE_CONTRAT_NON_REPONSE = "recherche.contrat.service.non.reponse";

    /**
     * Le web service de recherche contrat
     */
    @Autowired
    @Qualifier("rechercheContratWs")
    private IRechercherContratsWebService rechercheContratService;

    /**
     * Assembler
     */
    @Autowired
    @Qualifier("contrat2ContratConverter")
    private Converter<DTOContrat, IContrat> contrat2ContratConverter;

    /**
     * {@inheritDoc}
     * 
     * @throws AccueilClientRechercheContratException
     */
    public List<IContrat> rechercheContrats(IContratRecherche criteresRecherhe)
                    throws AccueilClientRechercheContratException {
        LOGGER.info("rechercheContrats");
        List<IContrat> result = null;

        DTODemande criteres = null;

        if (criteresRecherhe != null) {
            criteres = new DTODemande();
            criteres.setIdentifiantContrat(criteresRecherhe.getNumeroContrat());

            DTOSouscripteur souscripteur = new DTOSouscripteur();
            souscripteur.setNomCourant(criteresRecherhe.getNom());
            souscripteur.setCodePostal(criteresRecherhe.getCodePostal());
            souscripteur.setPrenom(criteresRecherhe.getPrenom());
            souscripteur.setIdentifiantPersonne(criteresRecherhe.getIdentifiantSouscripteur() != null ? criteresRecherhe
                            .getIdentifiantSouscripteur() : StringUtils.EMPTY);
            souscripteur.setReferenceClientApporteur(criteresRecherhe.getNumeroClientPortefeuille() != null ? criteresRecherhe
                            .getNumeroClientPortefeuille() : StringUtils.EMPTY);
            criteres.setSouscripteur(souscripteur);

            List<DTOPortefeuilleContrat> ptfs = new ArrayList<DTOPortefeuilleContrat>();
            DTOPortefeuilleContrat ptf = null;
            String[] cieptf = null;
            for (String portefeuille : criteresRecherhe.getPortefeuilles()) {
                ptf = new DTOPortefeuilleContrat();
                cieptf = portefeuille.split("-");
                ptf.setIdentifiant(cieptf[0]);
                ptf.setCompagnieProprietaire(cieptf[1]);
                ptfs.add(ptf);
            }
            criteres.getPortefeuillesContrat().addAll(ptfs);
            DTOProfilVehiculeAssure profilVehicule = new DTOProfilVehiculeAssure();
            profilVehicule.setNumeroImmatriculation(criteresRecherhe.getImmatriculation() != null ? criteresRecherhe
                            .getImmatriculation() : StringUtils.EMPTY);
            criteres.setProfilVehiculeAssure(profilVehicule);
        }

        try {
            DTOReponse reponse = rechercheContratService.rechercherContrats(criteres);

            if (reponse != null && reponse.isIndicateurAucunClient()) {
                throw new AccueilClientRechercheContratException(null, AUCUN_CLIENT);
            }
            if (reponse != null && reponse.isIndicateurPlusDe100Clients()) {
                throw new AccueilClientRechercheContratException(null, FORMULAIRE_AFFINE_CRITERES);
            }
            if (reponse != null && reponse.isIndicateurPlusDe40Contrats()) {
                throw new AccueilClientRechercheContratException(null, RESULTAT_TROP_LARGE);
            }

            if (reponse != null && CollectionUtils.isNotEmpty(reponse.getContrats())) {
                result = new ArrayList<IContrat>();
                for (Iterator<DTOContrat> iterator = reponse.getContrats().iterator(); iterator.hasNext();) {
                    IContrat contrat = contrat2ContratConverter.convert(iterator.next());
                    result.add(contrat);
                }
            }
        } catch (RechercherContratsException e) {
            LOGGER.error("Erreur technique lors de l'appel à la recherche contrat TOSCA: '{}'.", e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), SERVICE_CONTRAT_NON_REPONSE, e);
        }
        return result;
    }
}
